<template>
  <h1 ref="h1">子组件</h1>
  <p ref="p">{{ str }}</p>
  <button @click="change">change</button>
</template>
<script setup lang="ts">
import {
  onBeforeMount,
  onBeforeUnmount,
  onBeforeUpdate,
  onMounted,
  onRenderTracked,
  onRenderTriggered,
  onUnmounted,
  onUpdated,
  ref,
} from 'vue'

// vue3 使用组件化，将页面拆分为各个组件，进行组件的拼装和复用
// 在根组件中使用 import 导入子组件进行使用，不用进行注册

// 组件的声明周期：组件经历从创建，渲染，更新，卸载的过程，在每个过程上具有生命周期的钩子函数，在对应时刻触发
// Lifehook(() => {}) 生命周期钩子函数参数为回调，即在对应时刻触发回调
// setup => 组件创建阶段，可以在该阶段中请求数据，访问组件实例
// beforeMount => 组件渲染完成前
// Mounted => 组件渲染完成后，即可以访问页面的 DOM 结构，在 setup 中使用 ref 获取的 DOM 此时可以操作
// beforeUpdated => 组件更新完成前，指组件的页面完成更新前，即响应式数据发送变化，触发页面更新前
// 此时响应式数据变化而页面尚未更新，可以获取到页面 DOM 结构的一些更新前的数据
// Updated => 组件更新完成后，指组件的页面更新完成，可以获取页面 DOM 结构的更新后的数据
// beforeUnmount => 组件卸载完成前，可以完成组件卸载前释放内存的一些操作
// Unmounted => 组件卸载完成后
// RenderTracked => 组件渲染器收集依赖完成后
// RenderTriggered => 组件渲染器修改依赖完成后
// tracked tracked 的回调函数均可以接受 e 参数来访问组件的依赖对象
// 生命周期钩子函数以 on + lifeName 形式命名

const str = ref('=')
const change = () => {
  str.value += '='
}
const h1 = ref<HTMLElement>()
const p = ref<HTMLElement>()
// vue3 中 setup 取代了组件的 beforeCreate 和 Created
console.log('setup')
// onBeforeMount 组件渲染完成前，组件未渲染完成，不能操作 DOM 元素
onBeforeMount(() => {
  console.log('渲染完成前', h1.value)
})
// onMounted 组件渲染完成后，该阶段可以操作 DOM 元素
onMounted(() => {
  console.log('渲染完成后', h1.value)
})
// onBeforeUpdate 组件更新完成前，可以获取组件更新前页面 DOM 的数据
onBeforeUpdate(() => {
  console.log('更新完成前', p.value?.innerHTML)
})
// onUpdated 组件更新完成后，可以获取组件更新完成后页面 DOM 的数据
onUpdated(() => {
  console.log('更新完成后', p.value?.innerHTML)
})
// onBeforeUnmount 组件卸载完成前
onBeforeUnmount(() => {
  console.log('卸载完成前')
})
// onUnmounted 组件卸载完成后
onUnmounted(() => {
  console.log('卸载完成后')
})
onRenderTracked((e) => {
  console.log(e)
})
onRenderTriggered((e) => {
  console.log(e)
})
</script>
<style scoped></style>
